package com.example.demo.spring.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @author Rocket
 * @version 10.0.1
 * @date 2021-08-29 11:30 AM
 */
@Aspect
@Component
public class CalculatorLoggingAspect {

    @Before("execution (* com.example.demo.aop.ICalculator.add(..))")
    public void logBefore(JoinPoint point) {
        String methodName = point.getSignature().getName();
        Object args[] = point.getArgs();
        System.out.println("before......");
        System.out.println("method name: " + methodName);
        System.out.println("args: " + Arrays.asList(args));
    }

    @AfterReturning(pointcut="execution (* com.example.demo.aop.ICalculator.add(..))", returning = "result")
    public void getAddResult(JoinPoint point, Object result) {
        System.out.println("AfterReturning - get add result: " + result);
    }

    @AfterThrowing(pointcut="execution (* com.example.demo.aop.ICalculator.addError(..))", throwing = "e")
    public void loggingException(JoinPoint point, RuntimeException e) {
        System.out.println("Error is occurred, reason: " + e.getMessage());
    }


    @Around("execution (* com.example.demo.aop.ICalculator.add(..))")
    public void loggingAround(ProceedingJoinPoint point) {

        try {
            System.out.println("Around START");
            Object [] args = point.getArgs();
            for(Object arg: args) {
                Double d = (Double) arg;
                if(d == null || d >=0 ) {
                    System.out.println("Parameter should be negative number.");
                    return;
                }
            }
            Object proceed = point.proceed();
            System.out.println(proceed);
            System.out.println("Around END");
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}
